from pyglet.gl import *
from pyglet.window import key
import pyglet
import gamemap
import data
import anim3d
import puzzle
import sys
import random
import gamemenu
from gameobjects import *

class Game(object):
    num_puzzles = 5
    def __init__(self):
        self.win = pyglet.window.Window(800, 600) #640, 480)
        self.win.push_handlers(self)
        self.hand_cursor = self.win.get_system_mouse_cursor(self.win.CURSOR_HAND)
        self.def_cursor = self.win.get_system_mouse_cursor(self.win.CURSOR_DEFAULT)
        self.music = pyglet.media.load(data.filepath('bgmusic.wav'), streaming=False)
        self.player = pyglet.media.Player()
        self.player.queue(self.music)
        self.player.eos_action = self.player.EOS_LOOP

        #game specific stuff
        self.map = gamemap.Map()
        self.game_over = False 
        self.health = 100
        self.start_puzzle = False
        self.puzzle = None #puzzle.Puzzle(3)
        self.puzzle_count = 0
        self.game_start = False

        #load data for the game
        front_sky = pyglet.image.load(data.filepath('emeraldfog_bk.jpg'))
        down_sky = pyglet.image.load(data.filepath('emeraldfog_dn.jpg'))
        self.frsky_tex = front_sky.get_texture()
        self.dnsky_tex = down_sky.get_texture()
        (w, h) = self.win.get_size()
        self.health_text = pyglet.text.HTMLLabel('<h3><font color=#ffffff> Health:'+self.health.__str__()+'</font></h3>', x=0, y=h-25)
        self.game_result = pyglet.text.HTMLLabel('<h1><font color=#FF0000> You Lost </font></h1>', x=300, y=300)
        self.puzzle_text = pyglet.text.HTMLLabel('<h3><font color=#ffffff> Puzzles Solved:' + self.puzzle_count.__str__()+'</font></h3>', x=0, y=h-50)

        model = anim3d.Model(data.filepath('ffmodel.txt')) 
        hero_obj = anim3d.AnimObject()
        hero_obj.setModel(model)
        hero_obj.setAction('idle')

        #creating game objects
        self.hero =  GameObject() 
        self.hero.setAnimObj(hero_obj)
        self.hero.pos = [20, 10, 0]

        #pyglet stuff
        self.fps = pyglet.clock.ClockDisplay()
        pyglet.clock.schedule_interval(self.tick, 1/60.0)
        self.player.play()
        pyglet.app.run()

#    def on_eos(self):
#        self.player.queue(self.music)

    def reset(self):
        self.game_over = False
        self.health = 100
        self.start_puzzle = False
        self.puzzle = puzzle.Puzzle(3)
        self.puzzle_count = 0
        
    def on_key_press(self, symbol, modifier):
        if not(self.game_start):
            self.game_start = True
            return
        if self.game_over or self.start_puzzle:
            return 
        if symbol == key.SPACE and not(self.hero.vel[2]):
            self.hero.jump()

        vel = self.hero.vel 
        if symbol == key.UP:
            vel[1] = -1
        if symbol == key.LEFT:
            #if vel[1]:
            vel[0] = 1
        if symbol == key.RIGHT:
            #if vel[1]:
            vel[0] = -1
        self.hero.vel[0] = vel[0]
        self.hero.vel[1] = vel[1]
        
        if vel[2] :
            self.hero.setAnim('jump')
        elif vel[0] != 0 or vel[1] != 0:
            self.hero.setAnim('run')
             
    def on_key_release(self, symbol, modifier):
        if symbol == key.UP:
            self.hero.vel[1] = 0
        if symbol == key.LEFT or symbol == key.RIGHT:
            self.hero.vel[0] = 0
        v = self.hero.vel
        if v[0] == 0 and v[1] == 0 and v[2] == 0:
            self.hero.setAnim('idle')

    def tick(self, dt):
        if self.game_over or self.start_puzzle:
            return
        self.hero.update()
        #check if the hero is on path or not
        touching = self.map.isTouching(self.hero.pos)
        if not(touching):
            print "FALLING!!!"
            self.health -= 1
        #remove the old verts add new ones at end
        self.map.prune(self.hero.pos) 
        #collision check with other objects in game
        tmp = self.map.getObjHitList(self.hero.pos)
        if len(tmp) > 0:
            if tmp[0].name == 'puzzle':
                #save a screenshot for the puzzle
                pyglet.image.get_buffer_manager().get_color_buffer().save(data.filepath('screenshot.png'))
                #set the puzzle up for next round
                if self.puzzle_count:
                    self.puzzle = puzzle.Puzzle(random.choice([4,5,6]))
                else:
                    self.puzzle = puzzle.Puzzle(3)
                self.start_puzzle = True
            else:
                self.health -= 1
            print "Collision with " + tmp[0].name

        self.health_text.text = '<h3><font color=#ffffff> Health:'+self.health.__str__()+'</font></h3>'
        if self.health < 1:
            self.game_over = True


    def on_resize(self, width, height):
        glClearColor(0, 0, 0, 0.0)
        glEnable(GL_DEPTH_TEST)

    def drawGame(self):
        #leave the current projection as is for pyglet
        glMatrixMode(GL_PROJECTION)
        glPushMatrix()
        glLoadIdentity()
        #gluOrtho2D(-500, 500, -500, 500)
        dims = self.win.get_size()
        gluPerspective(50, float(dims[0])/dims[1], 0.1, 700)

        #leave the current modelview as is for pyglet
        glMatrixMode(GL_MODELVIEW)
        glPushMatrix()
        glLoadIdentity()
        cy = self.hero.pos[1]
        cx = self.hero.pos[0]
        #gluLookAt(0, -50, 40, 0, 0, 10, 0, 0, 1)
        gluLookAt(cx, cy+30, 20, cx, cy, 10, 0, 0, 1) #camera following hero

        p = self.hero.pos
        #game rendering
        #draw skybox
        glColor3f(1, 1, 0)
        (w, h) = (200, 100)
#                 p[0]+w, p[1]-250, -h/2, p[0]-w, p[1]-250, -h/2,
#                 p[0]+w, p[1]+20, -h/2, p[0]-w, p[1]+20, -h/2,
        verts = (p[0]+w, p[1]-250, h, p[0]-w, p[1]-250, h,
                 p[0]+w, p[1]-250, -h/2, p[0]-w, p[1]-250, -h/2,
                 p[0]+w, p[1]+20, -h/2, p[0]-w, p[1]+20, -h/2,
                 )
        tex = (0,1, 1, 1, 0, 0, 1, 0)
        front = verts[:3*4]
        down = verts[3*2:]

        #draw textured objects
        glColor3f(1, 1, 1)
        glEnable(GL_TEXTURE_2D)

        glBindTexture(GL_TEXTURE_2D, self.frsky_tex.id)
        pyglet.graphics.draw(4, pyglet.gl.GL_QUAD_STRIP, ('v3f', front), ('t2f', tex))

        glBindTexture(GL_TEXTURE_2D, self.dnsky_tex.id)
        pyglet.graphics.draw(4, pyglet.gl.GL_QUAD_STRIP, ('v3f', down), ('t2f', tex))

        self.map.draw((p[0], p[1]))

        self.hero.draw()
        glDisable(GL_TEXTURE_2D)
        
        #restore the proj modelview matrices for pyglet
        glMatrixMode(GL_PROJECTION)
        glPopMatrix()
        glMatrixMode(GL_MODELVIEW)
        glPopMatrix()

        #hud rendering
        self.fps.draw()
        self.health_text.draw()
        self.puzzle_text.draw()

    def on_draw(self):
        """pyglet event based draw function"""
        self.win.clear()
        if self.start_puzzle:
            self.puzzle.draw(self.win.get_size())
        else:
            if self.game_over:
                if self.puzzle_count == Game.num_puzzles:
                    self.game_result.text = '<h1><font color=#00FF00>You Won</font></h1>'
                    #print "WON!!"
                self.game_result.draw()
            else:
                if self.game_start: 
                    self.drawGame()
                else:
                    gamemenu.drawMenu()

    def on_mouse_press(self, x, y, button, modifiers):
        if not(self.start_puzzle):
            return
        if self.puzzle.isSolved():
            self.start_puzzle = False
            self.win.set_mouse_cursor(self.def_cursor)
            #increment the puzzle count
            self.puzzle_count += 1
            self.puzzle_text.text =  '<h3><font color=#ffffff> Puzzles Solved:'+self.puzzle_count.__str__()+'</font></h3>'
            if self.puzzle_count == Game.num_puzzles:
                self.game_over = True
        if pyglet.window.mouse.LEFT:
            indx = self.puzzle.getIndex((x+puzzle.Puzzle.xoffset, y+puzzle.Puzzle.yoffset))
            puzzle.Puzzle.start = indx
            print indx 

    def on_mouse_motion(self, x, y, dx, dy):
        if not(self.start_puzzle):
            return 
        indx = self.puzzle.getIndex((x+puzzle.Puzzle.xoffset, y+puzzle.Puzzle.yoffset))
        if indx > -1:
            #set hand pointer
            self.win.set_mouse_cursor(self.hand_cursor)
        else:
            #set normal pointer
            self.win.set_mouse_cursor(self.def_cursor)

    def on_mouse_release(self, x, y, button, modifier):
        if not(self.start_puzzle):
            return
        if pyglet.window.mouse.LEFT:
            indx = self.puzzle.getIndex((x+puzzle.Puzzle.xoffset, y+puzzle.Puzzle.yoffset))
            print indx
            if puzzle.Puzzle.start > -1 and indx > -1 and not(puzzle.Puzzle.start == indx):
                self.puzzle.swapIndices(puzzle.Puzzle.start, indx)
                if self.puzzle.isSolved():
                    print "Solved!!!"

